package exttable.formgenerator;


import java.awt.*;
import java.awt.event.*;
import java.text.DateFormatSymbols;
import java.util.*;

import javax.swing.*;

public class JTCalendarRu extends JPanel implements ActionListener {
    private static final long serialVersionUID = 1L;

    // ********SWING***********
    private JPanel controlPanel;

    private JPanel weekPanel;

    private JPanel monthPanel;

    private JComboBox monthsBox;

    private JComboBox yearsBox;

    private JComboBox localesBox;

    private JButton[] daysOfWeekButtons = null;

    private JButton[] daysOfMonthButtons = null;

    private JButton current = null;

    // ********VARIABLES********
    public final Color USUAL_DAY_COLOR = new Color(190, 200, 100);

    public final Color CURRENT_DAY_COLOR = new Color(190, 102, 100);

    public final Color BACKGROUND = new Color(160, 190, 80);

    public final Color WEEK = new Color(200, 150, 100);

    public final Color WINTER = new Color(111, 151, 250);//

    public final Color SPRING = new Color(160, 190, 80);

    public final Color SUMMER = new Color(230, 230, 130);

    public final Color AUTUMN = new Color(217, 145, 15);

    private Calendar calendar;

    private String[] locale = {"ru", "en"};
    private String date = null;
    private JFormattedTextField dataField;
    private JFrame frame;

    public JTCalendarRu(JFormattedTextField dataField, JFrame frame) {
        this.dataField = dataField;
        this.frame = frame;
        // ************************
        setLayout(new BorderLayout());
        setBackground(BACKGROUND);
        // *******INITIALIZATION***********

        calendar = new GregorianCalendar(TimeZone.getDefault(), new
                Locale(locale[0]));

        (controlPanel = new JPanel(new FlowLayout())).setOpaque(false);
        (monthPanel = new JPanel(new GridLayout(6, 7))).setOpaque(false);
        weekPanel = new JPanel(new GridLayout(1, 7));
        weekPanel.setBackground(WEEK);

        yearsInitialization();
        wholeInitialization(locale[0]);
        localesInitialization(locale[0]);

        yearsBox.setBackground(BACKGROUND);
        monthsBox.setBackground(BACKGROUND);
        localesBox.setBackground(BACKGROUND);
        yearsBox.addActionListener(this);
        monthsBox.addActionListener(this);
        localesBox.addActionListener(this);
        yearsBox.setFocusable(false);
        monthsBox.setFocusable(false);
        localesBox.setFocusable(false);

        controlPanel.add(monthsBox);
        controlPanel.add(yearsBox);
        controlPanel.add(localesBox);
        changeColor();

        JPanel calendarPanel = new JPanel(new BorderLayout());
        calendarPanel.setOpaque(false);

        calendarPanel.add(weekPanel, BorderLayout.NORTH);
        calendarPanel.add(monthPanel, BorderLayout.CENTER);
        calendarPanel.setPreferredSize(calendarPanel.getMinimumSize());

        add(controlPanel, BorderLayout.NORTH);
        add(calendarPanel);

    }

    // Вызывает методы инициализации тех частей, которые в будущем нужно будет
    // не один раз инизиализировать
    private void wholeInitialization(String locale) {
        monthsInitialization(locale);
        weekInitialization(locale);
        daysInitialization();
    }

    // инициализируюет JComboBox с перечнем языков
    private void localesInitialization(String currentLocale) {
        localesBox = new JComboBox();
        for (String res : locale) {
            localesBox.addItem(res);
        }
        localesBox.setSelectedItem(locale);
    }

    private void changeColor()// меняет цвет фона в зависимости от сезона
    {
        Color color = null;
        int month = calendar.get(Calendar.MONTH);
        if (month == 2 || month == 3 || month == 4)
            color = SPRING;
        if (month == 0 || month == 1 || month == 11)
            color = WINTER;
        if (month == 5 || month == 6 || month == 7)
            color = SUMMER;
        if (month == 8 || month == 9 || month == 10)
            color = AUTUMN;
        // если хотите отключить эту ерунду, можете просто здесь прописать
        // переменной color свое значение
        if (yearsBox != null)
            yearsBox.setBackground(color);
        if (monthsBox != null)
            monthsBox.setBackground(color);
        if (localesBox != null)
            localesBox.setBackground(color);
        setBackground(color);
    }

    // инициализируюет JComboBox с перечнем месяцев
    private void monthsInitialization(String locale) {
        String[] monthNames = DateFormatSymbols.getInstance(new
                Locale(locale)).getMonths();
        if (monthsBox == null)
            monthsBox = new JComboBox();
        monthsBox.removeAllItems();
        for (int i = 0; i < monthNames.length - 1; i++)
            // месяцев по закону 13, но т.к. нам закон не писан, ставим -1
            monthsBox.addItem(monthNames[i]);
        monthsBox.setSelectedIndex(calendar.get(Calendar.MONTH));
    }

    // JComboBox с годами
    private void yearsInitialization() {
        yearsBox = new JComboBox();
        for (int i = 0; i < 301; i++)
            yearsBox.addItem(String.valueOf(i + 1850));
        yearsBox.setSelectedItem(calendar.get(Calendar.YEAR) + "");
    }

    // инициализируюет кнопки, отображающие дни недели
    private void weekInitialization(String locale) {
        String[] daysOfWeek = DateFormatSymbols.getInstance(new
                Locale(locale)).getShortWeekdays();
        boolean firstTime = false;
        if (daysOfWeekButtons == null) {
            daysOfWeekButtons = new JButton[7];
            firstTime = true;
        }

        for (int i = 1; i < daysOfWeek.length; i++) {
            //System.out.println("Day: " + daysOfWeek[i].length());
            if (firstTime) {
                daysOfWeekButtons[i - 1] = new
                        JButton(daysOfWeek[i].length() > 2 ? daysOfWeek[i].substring(0, 3) :
                        daysOfWeek[i]);
                daysOfWeekButtons[i - 1].setFocusable(false);
                daysOfWeekButtons[i - 1].setForeground(Color.BLACK);
                daysOfWeekButtons[i - 1].setBorderPainted(false);
                daysOfWeekButtons[i - 1].setContentAreaFilled(false);
                weekPanel.add(daysOfWeekButtons[i - 1]);
            } else {
                daysOfWeekButtons[i -
                        1].setText(daysOfWeek[i].length() > 2 ? daysOfWeek[i].substring(0, 2)
                        : daysOfWeek[i]);
            }
        }
    }

    // Кнопки с числами месяца
    private void daysInitialization() {
        Calendar temp = new
                GregorianCalendar(calendar.get(Calendar.YEAR),
                calendar.get(Calendar.MONTH), calendar.get(Calendar.DAY_OF_MONTH));
        temp.set(Calendar.DAY_OF_MONTH, 1);
        int endOfMonth = temp.getActualMaximum(Calendar.DAY_OF_MONTH);
        int dayOfWeek = temp.get(Calendar.DAY_OF_WEEK);
        if (daysOfMonthButtons == null)
            daysOfMonthButtons = new JButton[38];// 7 дней * на 5 c гаком
        // недель +1(чтоб не
        // запутаться массив будет
        // начинаться с 1)
        for (int i = 1; i < daysOfMonthButtons.length; i++) {
            if (daysOfMonthButtons[i] == null) {
                daysOfMonthButtons[i] = new JButton();
                daysOfMonthButtons[i].addActionListener(this);
                daysOfMonthButtons[i].setBorderPainted(false);
                daysOfMonthButtons[i].setContentAreaFilled(false);
                daysOfMonthButtons[i].setCursor(new Cursor(Cursor.HAND_CURSOR));
                monthPanel.add(daysOfMonthButtons[i]);
            }
            if (i < dayOfWeek || i > endOfMonth + dayOfWeek - 1)
                daysOfMonthButtons[i].setVisible(false);
            else {
                daysOfMonthButtons[i] = daysOfMonthButtons[i];
                daysOfMonthButtons[i]
                        .setText(String.valueOf(i - dayOfWeek + 1));
                daysOfMonthButtons[i].setVisible(true);
            }
            daysOfMonthButtons[i].setForeground(Color.BLACK);
        }
        current =
                daysOfMonthButtons[calendar.get(Calendar.DAY_OF_MONTH) + dayOfWeek -
                        1];
        current.setForeground(Color.RED);
    }

    public void actionPerformed(ActionEvent e) {
        if (e.getSource() instanceof JButton) {
            current.setForeground(Color.BLACK);
            current = (JButton) e.getSource();
            current.setForeground(Color.RED);
            calendar.set(Calendar.DAY_OF_MONTH,
                    Integer.parseInt(current.getText()));

            refreshDate(calendar);
            frame.dispose();

        }
        if (e.getSource() instanceof JComboBox) {
            if (e.getSource() == yearsBox) {
                int month = monthsBox.getSelectedIndex();
                int day = calendar.get(Calendar.DAY_OF_MONTH);
                calendar.set(Calendar.YEAR, Integer.parseInt((String
                        .valueOf(yearsBox.getSelectedItem()))));
                if (day != calendar.get(Calendar.DAY_OF_MONTH)) // если было
                // выбрано 29
                // февраля
                // високосного
                // года
                // а потом пользователь решил изменить год на невисокосный, у
                // которого нет 29-го числа
                {
                    calendar.set(Calendar.DAY_OF_MONTH, 1);
                    calendar.set(Calendar.MONTH, month);
                }
                refreshDate(calendar);
            }
            if (e.getSource() == localesBox) {
                locale[0] = (String) localesBox.getSelectedItem();
            }
            if (e.getSource() == monthsBox) {
                if (monthsBox.getSelectedItem() != null) {
                    int month = monthsBox.getSelectedIndex();
                    int day = calendar.get(Calendar.DAY_OF_MONTH);
                    calendar.set(Calendar.MONTH, month);
                    if (day != calendar.get(Calendar.DAY_OF_MONTH)) // если было
                    // выбрано,
                    // например,
                    // 31
                    // декабря,
                    // а потом пользователь решил изменить месяц на февраль, у
                    // которого нет 31-го числа
                    {
                        calendar.set(Calendar.DAY_OF_MONTH, 1);
                        calendar.set(Calendar.MONTH, month);
                    }
                }
                refreshDate(calendar);
            }
            wholeInitialization(locale[0]);
            changeColor();
        }
    }

    public Calendar getDate() {
        return calendar;
    }

    public void setDate(Calendar date) {
        calendar = date;
    }

    private void refreshDate(Calendar calendar) {
        if (calendar.get(Calendar.DAY_OF_MONTH) > 9) {
            date = String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
        } else {
            date = "0" + String.valueOf(calendar.get(Calendar.DAY_OF_MONTH));
        }

        if (calendar.get(Calendar.MONTH) + 1 > 9) {
            date = date.concat("-");
        } else {
            date = date.concat("-0");
        }
        date = date.concat(String.valueOf(calendar.get(Calendar.MONTH) + 1));
        date = date.concat("-");
        date = date.concat(String.valueOf(calendar.get(Calendar.YEAR)));
        dataField.setText(date);

    }


}